package raytracing

import "math"

type Camera struct {
	origin          Vec3
	lowerLeftCorner Vec3
	horizontal      Vec3
	vertical        Vec3
}

func NewCamera(
	lookfrom, lookat, vup Vec3,
	vfov, aspectRatio, aperture, focus_dist float64,
) *Camera {
	theta := vfov / 180.0 * math.Pi
	h := math.Tan(theta / 2.0)
	viewportHeight := 2.0 * h
	viewportWidth := aspectRatio * viewportHeight

	w := lookfrom.Sub(lookat).UnitVector()
	u := vup.Cross(w).UnitVector()
	v := w.Cross(u)

	origin := lookfrom
	horizontal := u.MulScalar(viewportWidth)
	vertical := v.MulScalar(viewportHeight)
	lowerLeftCorner := origin.Sub(horizontal.DivScalar(2)).Sub(vertical.DivScalar(2)).Sub(w)

	return &Camera{
		origin:          origin,
		lowerLeftCorner: lowerLeftCorner,
		horizontal:      horizontal,
		vertical:        vertical,
	}
}

func (camera *Camera) GetRay(s, t float64) *Ray {
	return &Ray{
		Origin:    camera.origin,
		Direction: camera.lowerLeftCorner.Add(camera.horizontal.MulScalar(s)).Add(camera.vertical.MulScalar(t)).Sub(camera.origin),
	}
}
